//可选链操作符
// let object = {};
//
// if (object){
//     if (object.sayHello){
//         object.sayHello();
//     }
// }
//
// object && object.sayHello && object.sayHello();
// object?.sayHello?.();  //相当于三目运算符 当然这里可以更多
//
//
// //数组 数组与对象类似 也可以将原始类型、对象类型、函数类型、undefined和null赋值给数组
// let arr1 = [1,2,3];  //隐式声明 也叫数组字面量
// let arr2 = new Array();  //显式声明
//
// arr1[10] = 11;    //这里定义了第11个元素 索引为10的元素 中间的未具体定义元素都是undefined
//
// console.log(arr1);
//
// arr1[3] = 'luojinsheng';
// console.log(arr1[0],arr1[3],arr1[6],arr1[100]);   //JS数组不会越界 undefined
//
// console.log(arr1.length);
// arr1.length = 100;
// console.log(arr1.length);  //数组长度可以改变
// console.log(arr1);


// var a = 50;
// let arr = [
//     'abc',
//     [100, 200, 300],
//     {x: 100, y: 200},
//
//     function (num) {
//         return num;
//     },
//     function () {
//         return 600;
//     }(),
//     10 + a
// ];
// console.log(arr);
// console.log(arr[1][0]);
// console.log(arr[2].y);
// console.log(arr[3]);
// console.log(arr[3](1000));


// //数组常用方法
// //①Array.prototype.at(i) 根据指定i索引获取数组中的元素 可以接受负索引
// let arr = [100, 200, 300, 400, 500];
// arr[-1]=10000;  //可以设置负索引
// console.log(arr)  //[ 100, 200, 300, 400, 500, '-1': 10000 ]
// console.log(arr[0]);
// console.log(arr.at(-1));

// //②Array.prototype.concat() 连接两个或多个数组 返回一个新数组
// let arr1 = [1, 2, 3];
// let arr2 = [4, 5, 6];
// console.log(arr1.concat(arr2));  //[ 1, 2, 3, 4, 5, 6

// //③Array.prototype.indexOf() 返回在数组中可以找到一个给定元素的第一个索引，如果不存在，则返回-1
// let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
// console.log(arr.indexOf(3));  //2 说明是第三个元素
// console.log(arr.indexOf(300));  //-1 说明从索引4开始没有找到

//⑤Array.prototype.includes() 返回布尔值，表示某个数组是否包含给定的值，与字符串的includes方法类似
// let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
// console.log(arr.includes(3));
// console.log(arr.includes(300));

// //⑥Array.prototype.push() 在数组的末尾添加一个或多个元素，并返回新数组的长度，会改变原数组
// let arr1 = [1, 2, 3];
// let arr2 = [4, 5, 6];
// arr1.push(arr2);
// console.log(arr1);  //[ 1, 2, 3, [ 4, 5, 6 ] ]
// console.log(arr1.length);  //4

//⑦Array.prototype.pop() 删除数组的最后一个元素，并返回删除的元素，会改变原数组
// let arr1 = [1, 2, 3];
// arr1.pop()
// console.log(arr1);  //[ 1, 2 ]
// console.log(arr1.length);  //2

// //⑧Array.prototype.shift() 删除数组的第一个元素，并返回删除的元素，会改变原数组
// let arr1 = [1, 2, 3, 100, 200];
// arr1.shift()
// console.log(arr1);  //[ 2, 3 ]
// console.log(arr1.length);

// //⑨Array.prototype.unshift() 在数组的开头添加一个或多个元素，并返回新数组的长度，会改变原数组
// let arr1 = [1, 2, 3];
// let arr2 = [4, 5, 6];
// arr1.unshift(arr2);
// console.log(arr1);  //[ [ 4, 5, 6 ], 1, 2, 3 ]
// console.log(arr1.length);  //4

// ⑩Array.prototype.join() 使用指定连接字符串将所有数组元素连接成一个字符串，返回新数组，不会改变原数组
// let arr1 = [1, 2, 3, 100, 200];
// arr1.join()
// console.log(arr1.join('**'));  //[ 2, 3 ]
// console.log(arr1.length);

// //①①Array.prototype.slice(i,j) 从i索引开始到j索引结束（不包括j索引）截取数组，返回新数组，不会改变原数组
// let arr1 = [1, 2, 3, 100, 200];
// console.log(arr1.slice(1));  //包前不包后[ 2, 3, 100, 200 ]
// console.log(arr1.slice(1,3));  //包前不包后[ 2, 3 ]
// console.log(arr1.slice(-2));  //包前不包后[ 100, 200 ]
// console.log(arr1.slice(-2,-1));  //包前不包后[ 100 ]
// console.log(arr1.length);

//①②Array.prototype.reverse() 反转数组，返回新数组，不会改变原数组
// let arr1 = [1, 2, 3, 100, 200];
// let arr2 = arr1.reverse()
// console.log(arr2);

//①③Array.prototype.toString() 将数组转换为字符串，会改变原数组
// let arr1 = [1, 2, 3, 100, 200];
// console.log(arr1);
// console.log(typeof arr1);
// let arr2 = arr1.toString()
// console.log(arr2);
// console.log(typeof arr2);

//类数组对象
let obj = {
    0:100
}
console.log(obj[0]);

//字符串等类数组可以间接使用数组中的方法Array.prototype.方法.call(str)
str = 'luojinsheng'
console.log(str[0]);
console.log(str[3]);
console.log(Array.prototype.join.call(str));  //将数组的join方法应用到字符串上
console.log(Array.prototype.slice.call(str));  //将数组的slice方法应用到字符串上


let obj1={
    x:100,
    say:function (){
        console.log("hello");
    }
};
let obj2={};
obj1.say()
obj1.say.call(obj2)  //将obj1的say方法应用到obj2上


//数组去重
let arr = [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10];
let arr1 = [...new Set(arr)];
console.log(arr1);